﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using CaiyinSoft.NetGather.Protocol;


namespace CaiyinSoft.NetGather.NetGatherLib.Filter
{
    [Serializable]
    public class HTMLFilterBase : IHTMLFilter, IComparer<IHTMLFilter>
    {


        public virtual string FilterCaption 
        {
            get
            {
                return "";
            }
        }
        public virtual string ExpressionCaption 
        {
            get
            {
                return "";
            }
        }
        public virtual string Description 
        {
            get
            {
                return "";
            }
        }

        public bool RunOnce
        {
            get;
            set;
        }

        public bool Runabled 
        { 
            get;
            set;
        }

        public IHTMLAnalyzer HTMLAnalyzer 
        { get; set; }

        public int HTMLPosition { get; protected set; }

          /// 上级解析器
        /// </summary>
        public IHTMLFilter ParentFilter { get; set; }
        public List<IHTMLFilter> ChildFilters { get; protected set; }

        private string _inputHTML;
        public void SetInputHTML(string html)
        {
            _inputHTML = html;
        }

        public List<FilterResult> GetInputHTML()
        {
            if (string.IsNullOrEmpty(_inputHTML) && ParentFilter != null)
                return ParentFilter.FilterHTML();
            else
                return new List<FilterResult>(){(new FilterResult(0, _inputHTML))};
        }

        //public int FilterCount { get; set; }
        /// <summary>
        /// 为保存到XML文件，提供索引。
        /// </summary>
        public string OutputKey { get; set; }
        //public int OutputType { get; set; }

        /// <summary>
        /// 字符的解析方式
        /// 1 Regex
        /// </summary>
        //public int ParseType { get;  set; }
        public string FilterExpression { get; set; }
        public HTMLFilterBase()
        { 
            _InitParams();
        }

        private void _InitParams()
        {
            SetInputHTML ( "");
            OutputKey = Guid.NewGuid().ToString();
            //OutputType = 0;
            //ParseType = 0;
            FilterExpression = "";
            ChildFilters = new List<IHTMLFilter>();
            Runabled = true;
            HTMLPosition = 0;
        }

        public virtual void AddChildFilter(IHTMLFilter htmlFilter)
        {
            htmlFilter.ParentFilter = this;
            htmlFilter.HTMLAnalyzer = this.HTMLAnalyzer;
            if (!string.IsNullOrEmpty(this.OutputKey) &&  CaiyinSoft.NetGather.NetGatherUtility.Utility.IsGUID( htmlFilter.OutputKey))
            {
                htmlFilter.OutputKey = this.OutputKey ;
            }

            if (this.RunOnce)
            {
                htmlFilter.RunOnce = this.RunOnce;
            }

            ChildFilters.Add(htmlFilter);
        }

        public virtual IHTMLFilter GetFilter(string outputKey)
        {
            return ChildFilters.Find((e) => e.OutputKey.CompareTo(outputKey) == 0); 
        }

        /// <summary>
        /// 以指定方式解析HTML字符串，生成新字符串
        /// </summary>
        /// <returns></returns>
        public virtual List<FilterResult> FilterHTML()
        {
            return null;
        }

        /// <summary>
        /// 比较两个过滤器
        /// </summary>
        /// <param name="obj1"></param>
        /// <param name="obj2"></param>
        /// <returns></returns>
        public int Compare(IHTMLFilter obj1, IHTMLFilter obj2)
        {
            return obj1.HTMLPosition.CompareTo(obj2.HTMLPosition);
        }


        /// <summary>
        /// 解析HTML字符串时，附属执行的操作。
        /// </summary>
        /// <returns></returns>
        public virtual bool AssistExecute()
        {
            return true;
        }

        public virtual IHTMLFilter Clone()
        {
            HTMLFilterBase filter = new HTMLFilterBase();

            filter.HTMLAnalyzer = this.HTMLAnalyzer;
            foreach (var f in this.ChildFilters)
            {
                var fc = f.Clone();
                fc.ParentFilter = filter;
                filter.ChildFilters.Add(fc);
            }
            filter.Runabled = this.Runabled;
            filter.RunOnce = this.RunOnce;
            filter.OutputKey = this.OutputKey;
            filter.FilterExpression = this.FilterExpression;
            return filter;
        }

        [NonSerialized]
        private FilterForm _editform;
        public virtual InnerFormBase GetEditForm()
        {
            if (_editform == null)
            {
                _editform = new FilterForm();
                _editform.InfoSaveEventHandler += (sender, args) =>
                {
                    this.RunOnce = _editform.RunOnce;
                    this.OutputKey = _editform.OutputKey;
                    this.FilterExpression = _editform.FilterExpression;
                };
            }
            _editform.HTMLFilter = this;
            return _editform;
        }

        [NonSerialized]
        private Tools.DOMSourceForm _domform;
        public virtual InnerFormBase GetDomSourceForm(string testHTML)
        {
            if (_domform == null)
            {
                _domform = new CaiyinSoft.NetGather.NetGatherLib.Tools.DOMSourceForm();
                if (!string.IsNullOrEmpty(testHTML) && this.HTMLAnalyzer != null)
                    this.HTMLAnalyzer.SetInputHTML(testHTML);
                _domform.Filter = this;
            }
            return _domform;
        }
        public virtual InnerFormBase GetFilterResultForm(string testHTML)
        {
            Tools.FilterResultForm frm = new CaiyinSoft.NetGather.NetGatherLib.Tools.FilterResultForm();
            if (!string.IsNullOrEmpty(testHTML) && this.HTMLAnalyzer!=null)
                this.HTMLAnalyzer.SetInputHTML(testHTML);
            frm.Filter = this;
            return frm;
        }
        public virtual InnerFormBase GetHTMLSourceForm(string testHTML)
        {
            Tools.HTMLSourceForm frm = new CaiyinSoft.NetGather.NetGatherLib.Tools.HTMLSourceForm();
            if (!string.IsNullOrEmpty(testHTML) && this.HTMLAnalyzer != null)
                this.HTMLAnalyzer.SetInputHTML(testHTML);
            frm.Filter = this;
            return frm;
        }
        public virtual InnerFormBase GetRegexTestForm(string testHTML)
        {
            Tools.RegexTestForm frm = new CaiyinSoft.NetGather.NetGatherLib.Tools.RegexTestForm();
            if (!string.IsNullOrEmpty(testHTML) && this.HTMLAnalyzer != null)
                this.HTMLAnalyzer.SetInputHTML(testHTML);
            frm.Filter = this;
            return frm;
        }

        public int GetPosition(Dictionary<int, int> htmlLineInfo,int line, int position)
        {
            int revalue = 0;
            for (int i = 1; i < line; i++)
            {
                revalue += htmlLineInfo[i];
            }
            return revalue + position;
        }
    }

        #region IComparer接口比较方法的实现
    public class HTMLFilterCamparer : IComparer<IHTMLFilter>
    {
        public int Compare(IHTMLFilter obj1, IHTMLFilter obj2)
        {
            return obj1.HTMLPosition.CompareTo(obj2.HTMLPosition);
        }
    }
        #endregion

}
